/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.videolibrary.GUI;

import cz.muni.fi.pb138.videolibrary.database.Medium;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author vaculik
 */
public class MediaTableModel extends AbstractTableModel {

    private List<Medium> media;
    
    public MediaTableModel(List<Medium> m) {
        if (m == null) {
            throw new NullPointerException("List of media is null");
        }
        media = sortMediaById(m);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }

    @Override
    public int getRowCount() {
        return media.size();
    }

    @Override
    public int getColumnCount() {
        return 6;
    }

    public Medium getMedium(int index) {
        return media.get(index);
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (media == null || media.isEmpty()) {
            media = new ArrayList<>(videolibrary.getAllMedia());
        }
        if (media == null) {
            return null;
        }
        Medium medium = media.get(rowIndex);
        switch (columnIndex) {
            case 0:
                return medium.getId();
            case 1:
                return medium.getTitle();
            case 2:
                return medium.getAuthor();
            case 3:
                return medium.getContent();
            case 4:
                return medium.getAllLanguage();
            case 5:
                return medium.getAllCategory();
            default:
                throw new IllegalArgumentException("columnIndex");
        }
    }

    @Override
    public String getColumnName(int columnIndex) {
        switch (columnIndex) {
            case 0:
                return "ID";
            case 1:
                return "Title";
            case 2:
                return "Author";
            case 3:
                return "Content";
            case 4:
                return "Languages";
            case 5:
                return "Categories";
            default:
                throw new IllegalArgumentException("columnIndex");
        }
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case 0:
                return long.class;
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                return String.class;
            default:
                throw new IllegalArgumentException("columnIndex");
        }
    }

    public void setMedia(List<Medium> media) {
        this.media = sortMediaById(media);
        fireTableDataChanged();
    }

    public void removeAllMedia() {
        media.clear();
        fireTableDataChanged();
    }

    public void removeMedia(List<Medium> media, int[] rows) {
        if (!media.isEmpty()) {
            this.media.removeAll(media);
            fireTableRowsDeleted(rows[0], rows[rows.length - 1]);
        }
    }

    public void addMedium(Medium medium) {
        media.add(medium);
        int lastRow = media.size() - 1;
        this.fireTableRowsInserted(lastRow, lastRow);
    }

    public void updateMedium(Medium medium) {
        int index = 0;
        for (Medium tmp : media) {
            if (medium.getId() == tmp.getId()) {
                break;
            }
            index++;
        }
        media.set(index, medium);
        this.fireTableRowsUpdated(index, index);
    }

    private List<Medium> sortMediaById(List<Medium> media) {
        List<Medium> sortedMedia = new ArrayList<>(media);
        Collections.sort(sortedMedia, new IdComparator());
        return sortedMedia;
    }

    private class IdComparator implements Comparator<Medium> {

        @Override
        public int compare(Medium medium1, Medium medium2) {
            if (medium1.getId() > medium2.getId()) {
                return 1;
            } else if (medium1.getId() < medium2.getId()) {
                return -1;
            } else {
                throw new RuntimeException("Two media with identical id have been found.");
            }
        }
    }
}
